<script setup>
import { onMounted, onUnmounted, ref } from 'vue';
import { Base } from '../threejs/base';
import * as THREE from 'three';
import fish from '../assets/fish.svg';
import snake from '../assets/snake.png';
class Demo extends Base {
  mesh;
  m;
  time;
  controls = { color: 0xff0000 };
  geometry = { Geometry: 1 };
  initGui() {
    const g = this.gui.addFolder('调整这里试试');
    let colorChange = g.addColor(this.controls, 'color').name('色值');
    colorChange.onChange((value) => {
      console.log(value);
      for (let i = 0; i < this.scene.children.length; i++) {
        // 方式1
        // this.scene.children[i].material.uniforms.uColor.value.set(value); // 改变颜色为绿色
        // 方式2
        var newColor = new THREE.Color(this.controls.color);
        // 更新材质的颜色
        console.log(newColor);
        this.scene.children[i].material.uniforms.uColor.value.copy(newColor); // 如果颜色是uniform
      }
    });
    g.open();
  }

  initShader() {
    this.camera.position.set(0, 0, 4);
    this.camera.lookAt(new THREE.Vector3());
    this.renderer.setClearColor(0x160016, 1);
    this.ini01();
  }
  ini01() {
    // const geometry = new THREE.PlaneGeometry(1, 1);
    const row = 100; // 200
    const column = row;
    const count = row * column;
    const geometry = new THREE.BufferGeometry();
    const positions = new Float32Array(count * 3);
    const uvs = new Float32Array(count * 2);
    for (let j = 0; j < row; j++) {
      for (let i = 0; i < column; i++) {
        const x = i / column - 0.5; // -0.5-0.5
        const y = j / row - 0.5; // -0.5-0.5
        const u = x + 0.5; // 0-1
        const v = y + 0.5; // 0-1
        positions.set([x, y, 0], (i + j * column) * 3);
        uvs.set([u, v], (i + j * column) * 2);
      }
    }
    geometry.setAttribute("position", new THREE.BufferAttribute(positions, 3));
    geometry.setAttribute("uv", new THREE.BufferAttribute(uvs, 2));
    const vertexShader = /* GLSL */ `
      uniform float uTime;
      varying vec2 vUv;
      void main() {
       vUv = uv;
        vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
        gl_Position = projectionMatrix * mvPosition;
        gl_PointSize = 10.0 / -mvPosition.z;

      }
    `;

    const fragmentShader = /* GLSL */ `
      varying vec2 vUv;
      uniform sampler2D uTexture;
      void main() {
        vec4 color = texture2D(uTexture, vUv);
        gl_FragColor = vec4(color);
      }
    `;

    const material = new THREE.ShaderMaterial({
      vertexShader,
      fragmentShader,
      uniforms: {
        uTime: { value: 0 },
        uTexture: {
          value: new THREE.TextureLoader().load(snake),
        },
      },
      // wireframe: true,
    });
    const mesh = new THREE.Points(geometry, material);
    this.scene.add(mesh);
  }
  
  renderContent() {
    // this.time += 0.05;
    let time = this.clock.getElapsedTime();
    for (let i = 0; i < this.scene.children.length; i++) {
      this.scene.children[i].material.uniforms.uTime.value = time;
      this.scene.children[i].rotation.y = time / 100;
    }
  }
}

let ins;
const dom = ref();

onMounted(() => {
  ins = new Demo().init(dom.value);
});
onUnmounted(() => {
  ins.dispose();
});

const text = `
本示例主要学习了通过 uniforms 向着色器传递数据。示例主要代码如下：
\`\`\`
const m = new THREE.ShaderMaterial({
  uniforms: {
    uColor: { value: new THREE.Color(0xff0000) }
  },
  vertexShader: \`
    void main() {
      
      // position 是顶点的local坐标(Model坐标)
      // Model坐标 * ModelMatrix = World坐标；World坐标 * ViewMatrix = Camera坐标；Camera坐标 * ProjectionMatrix = 投影坐标

      gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }\`,
  fragmentShader: \`
    uniform vec3 uColor;  // 接收 uniforms 传过来的数据
    
    void main() {
      gl_FragColor = vec4(uColor, 1.0);
    }\`
});
\`\`\`
`;
</script>

<template>
  <div class="shader-box" ref="dom"></div>
  <v-md-preview :text="text"></v-md-preview>
</template>

<style scoped></style>
